/*
  Copyright © 2010  Vinícius dos Santos Oliveira

      This file is part of Touché.

      Touché is free software: you can redistribute it and/or modify
      it under the terms of the GNU Lesser General Public License as published
      by the Free Software Foundation, either version 3 of the License, or
      (at your option) any later version.

      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU Lesser General Public License for more details.

      You should have received a copy of the GNU Lesser General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */

#include "scene.h"
#include "widgets/pushbuttonitem.h"
#include "widgets/slideritem.h"
using namespace Touche;
#include <QGraphicsSvgItem>

#define TOUCHE_SHOULD_SKIP_THIS

#include "elements/textelement.h"
#include "elements/scribbleelement.h"
#include "elements/audioelement.h"
#include "elements/photoelement.h"

#undef TOUCHE_SHOULD_SKIP_THIS

#include <iostream>
using std::cout;
using std::endl;
#include <QGraphicsView>
#include <QStateMachine>
#include <QPropertyAnimation>
#include <QLinearGradient>
#include "colaborative/manager.h"
#include "colaborative/dialog.h"
#include "colaborativecontroller.h"

Stage *Scene::m_items = Stage::makeInstance();

Scene::Scene(qreal x, qreal y, qreal width, qreal height, QObject *parent) :
        QGraphicsScene(x, y, width, height, parent),
        timerId(0)
{
    QGraphicsScene::setItemIndexMethod(QGraphicsScene::NoIndex);
    {
        QLinearGradient gradient(QPointF(0., 0.), QPointF(0., 480.));
        gradient.setColorAt(0., Qt::darkCyan);
        gradient.setColorAt(1., Qt::white);
        QGraphicsScene::setBackgroundBrush(QBrush(QPixmap(":/gfx/png/background.png")));
    }

    QGraphicsScene::addItem(m_items);
    SliderItem *slider = new SliderItem(":/gfx/svg/zoom_slider.svg", ":/gfx/svg/zoom_icon.svg");
    slider->setMaximum(0x180);
    slider->setValue(0x80);
    QGraphicsScene::addItem(slider);
    connect(slider, SIGNAL(valueChanged(uint)), this, SLOT(zoomChanged(uint)));

    bottomBar.push_back(new PushButtonItem(":/gfx/svg/factory-text.svg"));
    bottomBar.push_back(new PushButtonItem(":/gfx/svg/factory-scribble.svg"));
    bottomBar.push_back(new PushButtonItem(":/gfx/svg/icon_photo.svg"));
    bottomBar.push_back(new PushButtonItem(":/gfx/svg/icon_audio.svg"));
    bottomBar.push_back(new PushButtonItem(":/gfx/svg/import_item.svg"));

    //bar background
    QGraphicsItem *icon_bg = new QGraphicsSvgItem(":/gfx/svg/icons_bg.svg");
    QGraphicsScene::addItem(icon_bg);
    icon_bg->setPos(730., 15.);

    //    bottomBar.push_back(new PushButtonItem(":/gfx/svg/open-file.svg"));
    bottomBar[0]->setPos(290., 416.);
    bottomBar[1]->setPos(370., 416.);
    bottomBar[2]->setPos(734., 16.);
    bottomBar[3]->setPos(734., 61.);
    bottomBar[4]->setPos(450., 416.);

    QGraphicsScene::addItem(bottomBar[0]);
    QGraphicsScene::addItem(bottomBar[1]);
    QGraphicsScene::addItem(bottomBar[2]);
    QGraphicsScene::addItem(bottomBar[3]);
    QGraphicsScene::addItem(bottomBar[4]);

    connect(bottomBar[0], SIGNAL(clicked()), this, SLOT(addTextItem()));
    connect(bottomBar[1], SIGNAL(clicked()), this, SLOT(addScribbleItem()));
    connect(bottomBar[2], SIGNAL(clicked()), this, SLOT(add_photo_item()));
    connect(bottomBar[3], SIGNAL(clicked()), this, SLOT(addAudioItem()));

    ColaborativeController::getInstance(m_items, this);
}

void Scene::itemMoved()
{
    if (!timerId)
        timerId = startTimer(1000 / 25);
}

void Scene::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event);

    QList<QGraphicsItem *> itemsList = items();
    bool itemsMoved = false;

    foreach (QGraphicsItem *item, itemsList) {
        if (dynamic_cast<DraggableToggleButton *>(item)) {
            StageActor *actor = reinterpret_cast<StageActor *>(item->data(0).value<QObject *>());
            if(actor){
                actor->calculateForces();

                if (actor->advance())
                    itemsMoved = true;
            }
        }
    }

    if (!itemsMoved) {
        killTimer(timerId);
        timerId = 0;
    }

    m_items->update();
}

void Scene::zoomChanged(uint value)
{
    qreal factor = static_cast<qreal>(value) / 0x100 + 0x.8p0;
    m_items->setScale(factor);
}

inline void Scene::addElement(Element *element)
{
    m_items->addToGroup(element);
}

void Scene::addTextItem()
{
    this->addElement(new TextElement);
}

void Scene::addScribbleItem()
{
    this->addElement(new ScribbleElement);
}

void Scene::addAudioItem()
{
    this->addElement(new AudioElement);
}

void Scene::add_photo_item()
{
    PhotoWidget *widget = new PhotoWidget(m_items);
    widget->exec();
    widget->deleteLater();
}
